#![allow(unused_imports, non_snake_case)]
use core::ffi::*;

use super::guiddef::*;
use super::windef::*;

pub const S_OK: HRESULT = 0;
pub const S_FALSE: HRESULT = 1;

// This trait should be implemented for all COM interfaces
pub trait Interface {
	// Returns the IID of the Interface
	fn uuidof() -> GUID;
}
// This trait should be implemented for all COM classes
pub trait Class {
	// Returns the CLSID of the Class
	fn uuidof() -> GUID;
}

#[repr(C)]
pub struct IUnknownVtbl {
	pub QueryInterface: unsafe extern "system" fn(This: *mut IUnknown, riid: REFIID, ppvObject: *mut *mut c_void) -> HRESULT,
	pub AddRef: unsafe extern "system" fn(This: *mut IUnknown) -> ULONG,
	pub Release: unsafe extern "system" fn(This: *mut IUnknown) -> ULONG,
}
#[repr(C)]
pub struct IUnknown {
	pub lpVtbl: *const IUnknownVtbl,
}
impl IUnknown {
	#[inline]
	pub unsafe fn QueryInterface(&self, riid: REFIID, ppvObject: *mut *mut c_void) -> HRESULT {
		((*self.lpVtbl).QueryInterface)(self as *const _ as *mut _, riid, ppvObject)
	}
	#[inline]
	pub unsafe fn AddRef(&self) -> ULONG {
		((*self.lpVtbl).AddRef)(self as *const _ as *mut _)
	}
	#[inline]
	pub unsafe fn Release(&self) -> ULONG {
		((*self.lpVtbl).Release)(self as *const _ as *mut _)
	}
}
impl Interface for IUnknown {
	#[inline]
	fn uuidof() -> GUID {
		GUID { Data1: 0x00000000, Data2: 0x0000, Data3: 0x0000, Data4: [0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46] }
	}
}
